#pragma once

#include <QString>
#include <unordered_map>
#include <mutex>
#include <QHash>

class StringPool
{
    struct hasher
    {
        uint32_t operator () (const QString &str) const
        {
            return qHash(str);
        }
    };
private:
    StringPool();
public:
    ~StringPool();
public:
    static uint32_t add(const QString &str);
    static QString at(uint32_t i);
    static void free(const QString &str);
private:
    uint32_t _add(const QString &str);
    QString _at(uint32_t i);
    void _free(const QString &str);
private:
    std::mutex locker;
    uint32_t lastIndex = 1;
    std::unordered_map<QString, uint32_t, hasher> ids = std::unordered_map<QString, uint32_t, hasher>(1024);
    std::unordered_map<uint32_t, QString> strings = std::unordered_map<uint32_t, QString>(1024);
    std::unordered_map<uint32_t, uint32_t> refCounts = std::unordered_map<uint32_t, uint32_t>(1024);
private:
    static StringPool *instance();
    static StringPool *_instance;
};

